/*
 * persona.cpp
 *
 *  Created on: 01/07/2014
 *      Author: nicolas
 */

#include "../interfaces/iBus.h"
#include "../interfaces/iPuertaEntrada.h"
#include "../interfaces/iPuertaSalida.h"
#include "../interfaces/iSala.h"
#include "../defines.h"
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <syslog.h>
#include <stdio.h>
#include <string.h>
#include "../comun/ServidorRemoto.h"

void viajar(iSala* sala, iBus* bus, Tipos::LugarDeSala lugar, int id) {

	char mostrar[80];

	sala->hacerCola(lugar);

	syslog(LOG_INFO, "Se puso en la cola de la sala");

	sala->recibirPermiso();

	syslog(LOG_INFO, "Obtuvo permiso para entrar a la sala");

	//Entra en la salaEntrada
	usleep(rand() % 3000000);

	syslog(LOG_INFO, "Entro a la sala");

	sprintf(mostrar, "La persona %i entro en la sala\n", id);
	write(fileno(stdout), mostrar, strlen(mostrar));

	sala->confirmarIngreso(lugar);

	sala->recibirPermisoSubirBus();

	syslog(LOG_INFO, "Obtuvo permiso para subir al bus");

	//Sube al bus
	usleep(rand() % 3000000);

	syslog(LOG_INFO, "Subio al bus");

	sprintf(mostrar, "La persona %i subio al bus\n", id);
	write(fileno(stdout), mostrar, strlen(mostrar));

	sala->confirmarSubidaBus(lugar);

	int idRepuesto = 0;
	do {
		idRepuesto = (bus->recibirPermisoBajar());
		if (idRepuesto > 0) {
			//cambiar del bus
			usleep(rand() % 3000000);
			bus->cambiarDeBus(idRepuesto);
			syslog(LOG_INFO, "Cambio al bus de repuesto %i", idRepuesto);
			sprintf(mostrar, "Cambio al bus de repuesto %i\n", idRepuesto);
			write(fileno(stdout), mostrar, strlen(mostrar));
		}
	} while (idRepuesto > 0);

	syslog(LOG_INFO, "Obtuvo permiso para bajar del bus");

	//Baja del bus
	usleep(rand() % 3000000);

	syslog(LOG_INFO, "Bajo del bus");
	sprintf(mostrar, "La persona %i bajo del bus\n", id);
	write(fileno(stdout), mostrar, strlen(mostrar));

	bus->confirmarBajada();
}

int main(int argc, char **argv) {

	if (argc != 2) {
		//error
		exit(1);
	}

	int id = atoi(argv[1]);

	char encabezado[80];
	sprintf(encabezado, "Persona %i", id);

	openlog(encabezado, LOG_PID | LOG_CONS, LOG_LOCAL0);

	syslog(LOG_INFO, "Se inicio Persona con args: %s", argv[1]);

	srand(time(NULL));

	ServidorRemoto rpc;
	int idPersona = rpc.pedirIdPersona(id);

	syslog(LOG_INFO, "Se obtuvo el id: %i", idPersona);

	sprintf(encabezado, "Persona %i, idGlobal %i", id, idPersona);

	openlog(encabezado, LOG_PID | LOG_CONS, LOG_LOCAL0);

	int caminoElegido = (rand() % CANT_ENTRADAS) + 1;

	iBus busEntrada(caminoElegido, idPersona, Tipos::LUGAR_ENTRADA);
	iSala salaEntrada(caminoElegido, idPersona);
	iPuertaEntrada entrada(caminoElegido, idPersona);
	syslog(LOG_INFO, "Se eligio entrar por el camino: %i", caminoElegido);

	caminoElegido = (rand() % CANT_ENTRADAS) + 1;
	iSala salaSalida(caminoElegido, idPersona);
	iBus busSalida(caminoElegido, idPersona,Tipos::LUGAR_ZOO);
	iPuertaSalida salida(caminoElegido, idPersona);
	syslog(LOG_INFO, "Se eligio salir por el camino: %i", caminoElegido);

	char mostrar[80];
	sprintf(mostrar, "La persona %i esta por entrar\n", idPersona);
	write(fileno(stdout), mostrar, strlen(mostrar));

	if (entrada.permitiEntrar()) {

		syslog(LOG_INFO, "Obtuvo permiso para entrar al parque");

		usleep(rand() % 3000000); // 0 a 3 secs

		syslog(LOG_INFO, "Entro al parque");

		sprintf(mostrar, "La persona %i entro al parque\n", idPersona);
		write(fileno(stdout), mostrar, strlen(mostrar));

		//Perdida de tiempo
		usleep(rand() % 3000000);

		viajar(&salaEntrada, &busEntrada, Tipos::LUGAR_ENTRADA, idPersona);

		//Perdida de tiempo
		usleep(rand() % 3000000);

		viajar(&salaSalida, &busSalida, Tipos::LUGAR_ZOO, idPersona);

		//salir
		salida.confirmarSalida();

		syslog(LOG_INFO, "Salio del parque");
		sprintf(mostrar, "La persona %i salio del parque\n", idPersona);
		write(fileno(stdout), mostrar, strlen(mostrar));

	} else {
		syslog(LOG_INFO, "No pudo entrar");
		sprintf(mostrar, "La persona %i no pudo entrar\n", idPersona);
		write(fileno(stdout), mostrar, strlen(mostrar));
	}

}

